package idv.arthur.widgets;

import idv.arthur.jenkins.JobDepStruc;
import idv.arthur.structures.ModNode;
import idv.arthur.structures.S2;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.PostMethod;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.jvnet.hudson.client_demo.URLConnectionUtil;

public class Widgets {
	public static String JENKINSURL = "http://10.144.97.99:8330/jenkins/";
	public final String JENKINS_USR = "arthymoment";
	public final String JENKINS_PWD = "arthymoment";
	public final String APSERVER_HOST = "http://10.144.97.100:8080/DevOps/";
	public final int WAITING = 3000; // 等待間隔秒數
	public final long WAITSECOND = 999999999;

	public void waitSeconds() {
		for (int i = 0; i < WAITSECOND; i++) {
		}
	}
	
	public boolean setJenkinsJob() {
		boolean result = false;

		String jobName ="MR_BL_ccBananna";
		String urlStr = JENKINSURL+"job/"+jobName+"/config.xml";
		String postBuildURL = APSERVER_HOST+"TriggerNext?ccccccccc";
		Map<String,Object> map = new HashMap<String,Object>();
        InputStream ins = null;
        FileInputStream fis = null;
        File tmpFile = null;
        try {
        	// 連線取得資料
            ins = URLConnectionUtil.doGet(urlStr,true,JENKINS_USR,JENKINS_PWD,map);
    		SAXReader reader = new SAXReader();
    		Document document = reader.read(ins);
    		Element root = document.getRootElement();
    		root.element("postbuilders").element("jenkins.plugins.http__request.HttpRequest").element("url").setText(postBuildURL);		
    		PostMethod postMethod = new PostMethod(urlStr);
    		postMethod.setRequestHeader("Content-type","application/xml; charset=UTF-8");
    		tmpFile = new File("tmp"+System.currentTimeMillis()+".xml");
    		fis = new FileInputStream( saveToFile(tmpFile, document) );
    		postMethod.setRequestBody(fis);
    		
    		HttpClient client = new HttpClient();
    		client.getParams().setAuthenticationPreemptive(true);
    		client.getState().setCredentials( AuthScope.ANY, new UsernamePasswordCredentials(JENKINS_USR,JENKINS_PWD) );
    		client.executeMethod(postMethod);
    		result= true;
        } catch(Exception e) {
        	
        } finally {
        	if (tmpFile != null) { if (tmpFile.exists()) { tmpFile.delete(); } }
        	try {
        		if (ins != null) {ins.close();}
        		if (fis != null) {fis.close();} 
        	} catch(Exception e) { e.printStackTrace(); }
        	
        }
        
        
		
	
		
		
		return result;
	}
	

	public String getJenkinsJobResult(String jobName, int jobSN, String subsysId)
			throws Exception {
		String res = "";

		final String urlStr = JENKINSURL + "job/" + jobName + "/" + jobSN
				+ "/api/xml";
		final Map<String, Object> map = new HashMap<String, Object>();
		try {
			InputStream ins = URLConnectionUtil.doGet(urlStr, false,
					JENKINS_USR, JENKINS_PWD, map);
			final SAXReader reader = new SAXReader();
			final Document document = reader.read(ins);
			ins.close();

			Element root = document.getRootElement();
			Iterator<Element> it = root.elementIterator();
			boolean isDone = false;
			while (it.hasNext()) {
				Element e = it.next();
				if ("result".equalsIgnoreCase(e.getName())) {
					res = e.getText();
					isDone = true;
					System.out.println("\t完成了");
				}
			}

			if (!isDone) {
				System.out.println(jobName + "驅動了，還沒好，再等一下："
						+ System.currentTimeMillis());
				waitSeconds();
				res = getJenkinsJobResult(jobName, jobSN, subsysId);
			}
		} catch (FileNotFoundException e) {
			System.out.println(jobName + "還沒驅動，再等一下："
					+ System.currentTimeMillis());
			waitSeconds();
			getJenkinsJobResult(jobName, jobSN, subsysId);
		}

		return res;

	}

	public void triggerJenkin(JobDepStruc jd) throws Exception {
		final String subsysId = "BL";
		final String modId = jd.getModId();
		final int jobSN = jd.nextBuildNumber();
		final PostMethod postMethod = new PostMethod(JENKINSURL + "job/"
				+ modId + "/build?token=" + modId);
		final HttpClient client = new HttpClient();
		final int returnCode = client.executeMethod(postMethod);
		waitSeconds();
		waitSeconds();
		waitSeconds();
		waitSeconds();
		if (returnCode == 201) {
			System.out.println("驅動建置" + jd.getModId() + "成功");
			System.out.println("開始處理" + modId);
			waitSeconds();
			final String result = getJenkinsJobResult(modId, jobSN, subsysId);
			if (jd.getDown().size() > 0) {
				System.out.println("它有觸發其它模組，等一下");
				waitSeconds();
				for (int i = 0; i < jd.getDown().size(); i++) {
					triggerJenkin(jd.getDown().get(i));
				}
			} else {
				System.out.println(jd.getModId() + "後沒有觸發其它模組");
			}
		} else {
			System.out.println("驅動建置" + jd.getModId() + "失敗");
		}
	}

	public JobDepStruc buildTree(JobDepStruc nex) throws IOException {
		String urlStr = JENKINSURL + "job/" + nex.getModId() + "/config.xml";

		JobDepStruc selDbls = new JobDepStruc(nex.getModId());
		selDbls.setNextBuildNumber(selDbls.nextBuildNumber());
		selDbls.setUp(nex);
		Map<String, Object> map = new HashMap<String, Object>();

		// 連線取得資料
		InputStream res = null;
		SAXReader reader = new SAXReader();
		try {
			res = URLConnectionUtil.doGet(urlStr, false, JENKINS_USR,
					JENKINS_PWD, map);
			Document document = reader.read(res);
			Element root = document.getRootElement();
			Iterator<Element> it = root.elementIterator();
			ArrayList<JobDepStruc> dbss = new ArrayList<JobDepStruc>();
			while (it.hasNext()) {
				Element e2 = it.next();
				if ("publishers".equalsIgnoreCase(e2.getName())) {
					if (e2.elementIterator().hasNext()) {
						String tmpStr = e2.element("hudson.tasks.BuildTrigger")
								.element("childProjects").getText();
						String[] downStreamModId = tmpStr.split(","); // 因為可能下游不只一個

						for (int i = 0; i < downStreamModId.length; i++) {
							JobDepStruc nxs = new JobDepStruc(
									downStreamModId[i].trim());
							nxs.setUp(selDbls);
							dbss.add(buildTree(nxs));
						}
					}
				}
			}
			selDbls.setDown(dbss);
			selDbls.setLeaf((dbss.size() == 0));

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			res.close();
		}

		return selDbls;
	}

	public ArrayList<ModNode> getModBEdependency(String modId, boolean isAuth,
			boolean isCascade, String urlStr, String usr, String pwd)
			throws Exception {
		ArrayList<ModNode> mns = new ArrayList<ModNode>();

		Map<String, Object> map = new HashMap<String, Object>();

		// 連線取得資料
		InputStream res = null;
		SAXReader reader = new SAXReader();

		try {
			res = URLConnectionUtil.doGet(urlStr, isAuth, usr, pwd, map);
			Document document = reader.read(res);
			Element root = document.getRootElement();
			Iterator<Element> it = root.elementIterator();

			while (it.hasNext()) {
				Element e2 = it.next();
				if ("publishers".equalsIgnoreCase(e2.getName())) {
					if (e2.elementIterator().hasNext()) {
						String tmpStr = e2.element("hudson.tasks.BuildTrigger")
								.element("childProjects").getText();
						String[] downStreamModId = tmpStr.split(","); // 因為可能下游不只一個

						for (int i = 0; i < downStreamModId.length; i++) {
							ModNode mn = new ModNode();
							mn.setCurrentNode(modId);
							mn.setDownSreamNode(downStreamModId[i]);
							mns.add(mn);
						}
					}
				}
			}
		} catch (Exception e) {
			throw e;
		} finally {
			res.close();
		}

		return mns;
	}

	public File saveToFile(File storedFile, Document document) {
		if (storedFile.exists())
			storedFile.delete();

		FileOutputStream fos = null;
		OutputStreamWriter osw = null;
		XMLWriter writer = null;
		try {
			storedFile.createNewFile();

			OutputFormat format = OutputFormat.createPrettyPrint();
			format.setEncoding("utf-8");
			fos = new FileOutputStream(storedFile);
			osw = new OutputStreamWriter(fos, Charset.forName("utf-8"));
			writer = new XMLWriter(osw, format);
			writer.write(document);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (writer != null) { writer.close(); }
				if (osw != null) { osw.close(); }
				if (fos != null) { fos.close(); }
			} catch (IOException e) { e.printStackTrace();}
		}
		return storedFile;
	}

	public ArrayList<String> getSVN4SubsysConnInfo(String subsysId,
			int svnTypeId) throws Exception {

		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		final ArrayList<String> connSVNInfo = new ArrayList<String>();

		try {
			conn = getConn();
			ps = conn
					.prepareStatement("SELECT svnUrl,svnUsr,svnPwd FROM mpsubsys2svn WHERE subsysId=? AND svnTypeId=?");
			ps.setString(1, subsysId);
			ps.setInt(2, svnTypeId);
			rs = ps.executeQuery();
			rs.next();

			connSVNInfo.add(rs.getString("svnUrl"));
			connSVNInfo.add(rs.getString("svnUsr"));
			connSVNInfo.add(rs.getString("svnPwd"));

		} catch (Exception e) {
			throw e;
		} finally {
			if (rs != null) {
				rs.close();
			}
			if (ps != null) {
				ps.close();
			}
			if (conn != null) {
				conn.close();
			}
		}

		return connSVNInfo;
	}

	public Connection getConn() {
		Connection conn = null;

		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection(
					"jdbc:mysql://10.144.136.54:3306/sysflow", "Arthur",
					"abcd1234");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}
	
	public S2 querySourceSVN(String subsysId,String modId) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		S2 s2= new S2();
		try {
			conn = getConn();
			final String sql = "SELECT olSVNpath,mrSVNpath FROM modunits WHERE modUnitId=? AND subsysId=?";
			ps = conn.prepareStatement(sql);
			ps.setString(1, modId);
			ps.setString(2, subsysId);
			rs = ps.executeQuery();
			rs.next();
			s2.setS1( rs.getString("mrSVNpath") );
			s2.setS2( rs.getString("olSVNpath") );
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if ( rs !=null ) {rs.close();}
				if ( ps !=null ) {ps.close();}
				if ( conn !=null ) {conn.close();}	
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return s2;
	}
}
